package edu.pitt.dbmi.monarch.rest;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import java.io.IOException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import org.apache.http.client.ClientProtocolException;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

/**
 * Author : Jeremy Espino MD
 * Created  6/17/13 2:40 PM
 */
@Path("/owlsim")
public class OwlSimService extends AbstractRestService {


    @GET
    @Path("/mgiSearchByDisease")
    public Response mgiSearch(@QueryParam("diseaseId") String id) {

        //{"A": {"id":"OMIM:600737","label":"INCLUSION BODY MYOPATHY 2, AUTOSOMAL RECESSIVE"},"B": {"id":"MGI:3028973","label":"Shh<tm1Chg>/Shh<tm1Chg>"},"num_annots_A":11,"num_annots_B":9,"simJ":0.07058824,"BMAasymJ":null,"BMAsymJ":null,"SimGIC":null,"BMAasymIC_terms": [{"id":"HP:0000004","label":"Onset and clinical course"},{"id":"HP:0000001","label":"All"},{"id":"HP:0000118","label":"Phenotypic abnormality"}],"BMAsymIC_terms": [{"id":"HP:0000004","label":"Onset and clinical course"},{"id":"HP:0000001","label":"All"},{"id":"HP:0000118","label":"Phenotypic abnormality"}]},


        ArrayList<HashMap<String, Object>> response = new ArrayList<HashMap<String, Object>>();




        ClientConfig cc = new DefaultClientConfig();
        cc.getClasses().add(JacksonJsonProvider.class);
        Client clientWithJacksonSerializer = Client.create(cc);

        // check to see that the disease id is one of the known disease terms

        // issue query to nif
        //http://beta.neuinfo.org/services/v1/federation/data/nlx_152525-10?filter=a:OMIM_104300
        ClientConfig config = new DefaultClientConfig();
        config.getClasses().add(JacksonJsonProvider.class);
        Client client = Client.create(config);
        WebResource service = client.resource(UriBuilder.fromUri("http://beta.neuinfo.org/services/v1/federation/data/nlx_152525-10?filter=a:OMIM_104300").build());

        HashMap result = service.accept(MediaType.APPLICATION_JSON).get(HashMap.class);

        List l = ((List) ((HashMap) result.get("result")).get("result"));

        //Map abMap = HashMap<String,>

        for (Object i : l) {
            System.out.println((Map) i);
            System.out.println(((Map) i).get("e_uid"));
        }






        return generateResponse(null);
    }

    public static void main(String[] args) {
        OwlSimService owlSimService = new OwlSimService();
        owlSimService.mgiSearch("");
    }


    @GET
    @Path("/getOutput")
    public Response getOutput(@QueryParam("id") String id) {
        Map<String, String> response = new HashMap<String, String>();
        Thread runningThread = Env.getInstance().getRunningThread();
        SimSearch simSearcher = Env.getInstance().getSimSearcher();
        response.put("id", id);

        if (runningThread != null && simSearcher != null && runningThread.getName().equalsIgnoreCase(id) && runningThread.isAlive()) {
            response.put("startTime", simSearcher.getStartTime() + "");
            long runTimeMillis = (System.currentTimeMillis() - simSearcher.getStartTime());
            int seconds = (int) (runTimeMillis / 1000) % 60;
            int minutes = (int) ((runTimeMillis / (1000 * 60)) % 60);
            int hours = (int) ((runTimeMillis / (1000 * 60 * 60)) % 24);
            response.put("runTime", String.format("%d:%d:%d", hours, minutes, seconds));
        } else {

            // check if output exists
            try {
                String outputFn = simSearcher.getOutputFileName();
                String fileOutput = readFile(outputFn);
                response.put("output", fileOutput);
            } catch (FileNotFoundException e) {
                response.put("error", "file not found");
                e.printStackTrace();
            } catch (IOException e) {
                response.put("error", "could not parse output file");
                e.printStackTrace();
            }

        }


        return generateResponse(response);


    }

    @GET
    @Path("/simSearch2")
    public Response simSearch2(@QueryParam("id") String id,
                               @QueryParam("inference_axis") String inferenceAxis,
                               @QueryParam("target_species") String targetSpecies) {


        Map<String, String> response = new HashMap<String, String>();

        Thread t = Env.getInstance().getRunningThread();
        if (t != null && t.isAlive()) {
            response.put("error", "search job still running");
            response.put("runningId", t.getName());
            return generateResponse(response);
        }

        String runId = System.currentTimeMillis() + "";


        try {

            String[] instances1 = {
                    "OMIM:142945", "HP:0000006",
                    "OMIM:142945", "HP:0000126",
                    "OMIM:142945", "HP:0000272",
                    "OMIM:142945", "HP:0000366",
                    "OMIM:142945", "HP:0000601",
                    "OMIM:142945", "HP:0001360",
                    "OMIM:142945", "HP:0003829",
                    "OMIM:142945", "HP:0009914"};

            String[] labels1 = {
                    "OMIM:142945", "HOLOPROSENCEPHALY 3"
            };

            String[] instances2 = {
                    "MGI:1919638", "MP:0009576",
                    "MGI:1919638", "MP:0002233",
                    "MGI:1919638", "MP:0011089",
                    "MGI:1919638", "MP:0000547",
                    "MGI:1919638", "MP:0000592",
                    "MGI:1919638", "MP:0002111",
                    "MGI:1919638", "MP:0001200",
                    "MGI:1919638", "MP:0002098"
            };

            String[] labels2 = {
                    "MGI:1919638", "Ripk4"
            };

            SimSearch simSearch = new SimSearch();
            //simSearch.init(runId, null, null, null, null, null, instances1, labels1,
            //        MouseGenotypePhenotypeMapping.getInstance().getInstances(),
            //        MouseGenotypePhenotypeMapping.getInstance().getLabels());

            simSearch.init(runId, null, null, null, null, null, instances1, labels1,
                    instances2,
                    labels2);


            Thread thread = new Thread(simSearch, runId);
            thread.start();

            Env.getInstance().setRunningThread(thread);
            Env.getInstance().setSimSearcher(simSearch);

            response.put("id", runId);


        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return generateResponse(response);
    }


    // handle = simSearch(id, inference_axis,target_type,target_species)
    // handle = simSearch( [ HPO1, HPO2,.....],inference_axis,target_type,target_species)
    @GET
    @Path("/simSearch")
    public Response simSearch(@QueryParam("id") String id,
                              @QueryParam("inference_axis") String inferenceAxis,
                              @QueryParam("target_species") String targetSpecies) {

        Map<String, String> result = new HashMap<String, String>();
        result.put("handle", "1");

        return generateResponse(result);
    }


//    my_source_ids = getQuerySource(handle)
//    my_target_type = getTargetType(handle)
//    my_axis = getInferenceAxis(handle)
//    my_target_species = getTargetSpecies(handle)
//    my_metrics = getMetricsCalculate (handle)


    //    results = getMatches(handle, n=50, similarity_metric=”SIMJ”)
    @GET
    @Path("/getMatches")
    public Response getMatches(@QueryParam("handle") String id,
                               @QueryParam("n") Integer n,
                               @QueryParam("similarity_metric") String similarityMetric) throws IOException {


        String dummyFileout = readResource("/testshhgenotypemps.json");

        return generateStringResponse(dummyFileout);
    }


    //    subsumer = getSubsumer(handle,sourceid,targetid)
    @GET
    @Path("/getSubsumer")
    public Response getSubsumer(@QueryParam("handle") String id,
                                @QueryParam("sourceid") String sourceId,
                                @QueryParam("targetid") String targetId) throws IOException {


        String dummyFileout = readResource("/testshhgenotypemps-compare-atts.json");

        return generateStringResponse(dummyFileout);
    }

//

//    path = getPathToParent(handle,id,target)
//    path = getPathToParent(handle,id,target,rel)

//    results  = getRelationshipTypes(objid)
//    result  = getRelated(obid,relation)
//    results = getRelated(obid)
//

//    [ (e1,q1), ..(en,qn)] = getLogicalEquivalences(id)

//    candidates = getMatchingTerms(ontologyID,substring)
//
//    parents = getParents(termID, rel =isA)
//
//    children = getChildren(termID, rel =isA)
//
//    sibs = getSiblings termID,rel=isA)



}